﻿using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;

namespace _3DSensor
{
    public class PaintGestureApp : AbstractGestureWindow, IGesturable
    {
        bool _paintStarted;

        bool _penUp = true;

        PaintGestureAppWindow helpWindow = new PaintGestureAppWindow();

        public PaintGestureApp(GestureRecogniser recogniser)
        {
            recogniser.RegisterObservers(this);
            InitializeComponent();
        }
        public void ReceivedGesture(GestureBase gesture, double epsilon)
        {
            // let the paint move based on the gestures provided

            //but first check if the application is active or not
            if (!IsAppActive)
            {
                helpWindow.Visibility = Visibility.Hidden;
                return;
            }
            if (!_paintStarted)
            {
                Util.startProcess("mspaint.exe");

                _penUp = false;
                _paintStarted = true;
            }
            helpWindow.Visibility = Visibility.Visible;
            if (gesture.InnerGesture.Equals(Gesture.LeftHandOut))
            {
                _penUp = false;
            }
            else if (gesture.InnerGesture.Equals(Gesture.Off))
            {
                _penUp = true;

            }
            else if (gesture.InnerGesture.Equals(Gesture.Close))
            {
                if (_paintStarted)
                {
                    Util.killProcess("mspaint.exe");
                    cursorSizeSet = false;
                }
                _paintStarted = false;
                IsAppActive = false;
            }
            else if (gesture.InnerGesture.Equals(Gesture.Move))
            {
                double xVal = gesture.Value;
                double yVal = gesture.Value2;
                //move the cursor around
                SetCursorPosition((int) xVal, (int) yVal);
            }
        }

        private Boolean cursorSizeSet = false;

       /// <summary>
       /// 
       /// </summary>
       /// <param name="x"></param>
       /// <param name="y"></param>
        private void SetCursorPosition(int x, int y)
        {
            // Get a handle to an application window.
            var appHandle = FindWindow(null, "Untitled - Paint");

           if (appHandle == IntPtr.Zero) return;
           SetForegroundWindow(appHandle);
            if(!cursorSizeSet)
            {
                
                //Set the cursor size
                SendKeys.SendWait("^{ADD}");
                SendKeys.SendWait("^{ADD}");
                SendKeys.SendWait("^{ADD}");
                cursorSizeSet = true;
            }

           RECT lpRect;
           GetWindowRect(appHandle, out lpRect);

           //Rescale from 640x480 to the correct dimensions
           var newX = (int)(x / 640.0 * (lpRect.Right - lpRect.Left)) + lpRect.Left;
           var newY = (int)(y / 480.0 * (lpRect.Bottom - lpRect.Top)) + lpRect.Top;

           SetCursorPos(newX, newY);
           mouse_event(_penUp ? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
        }


        [DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
        public static extern IntPtr FindWindow(string lpClassName,
            string lpWindowName);

        // Activate an application window.
        [DllImport("USER32.DLL")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll")]
        private static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, uint dwExtraInf);

        [DllImport("user32.dll")]
        public static extern bool SetCursorPos(int x, int y);

        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hwnd, uint nCmdShow);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;        // x position of upper-left corner
            public int Top;         // y position of upper-left corner
            public int Right;       // x position of lower-right corner
            public int Bottom;      // y position of lower-right corner
        }

        private const UInt32 MOUSEEVENTF_LEFTDOWN = 0x0002;
        private const UInt32 MOUSEEVENTF_LEFTUP = 0x0004;
        private const UInt32 MOUSEEVENTF_ABSOLUTE = 0x8000;
        private const UInt32 SW_MAXIMIZE = 3;
    }
}










